package org.springblade.modules.ad.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.ad.entity.AdGroup;
import org.springblade.modules.ad.entity.AdOU;
import org.springblade.modules.ad.entity.AdUser;
import org.springblade.modules.ad.service.ADSync;
import org.springblade.modules.ad.service.AdGroupService;
import org.springblade.modules.ad.service.AdOUService;
import org.springblade.modules.ad.service.AdUserService;
import org.springblade.modules.ad.utils.Result;
import org.springblade.modules.dingtalk.entity.DeptSyncOU;
import org.springblade.modules.dingtalk.entity.DingTalkUser;
import org.springblade.modules.dingtalk.mapper.DeptSyncOUMapper;
import org.springblade.modules.dingtalk.mapper.DingTalkUserMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ADSyncImpl implements ADSync {
	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private AdOUService adOUService;
	@Resource
	private AdUserService adUserService;
	@Resource
	private AdGroupService adGroupService;
	@Resource
	private DingTalkUserMapper dingTalkUserMapper;
	@Resource
	private DeptSyncOUMapper deptSyncOUMapper;

	@Override
	public Result syncAdDataInfo() {
		Result result = ouTree();
		return result;

	}

	@Override
	public Result syncEmpData(String name) {
		// TODO
		return null;
	}


	/**
	 * 封装部门数机构
	 *
	 * @return
	 */
	private Result ouTree() {
		// 获取部门信息
		List<DeptSyncOU> deptSyncOUList = deptSyncOUMapper.selectList(Wrappers.emptyWrapper());
		Map<Long, List<DeptSyncOU>> deptMap = deptSyncOUList.stream().collect(Collectors.groupingBy(DeptSyncOU::getParentId));
		// 最上层节点
		Long topDeptId = 0l;
		DeptSyncOU deptSyncOU = deptMap.get(topDeptId).get(0);
		AdOU adOU = getDeptTree(deptMap, deptSyncOU);
		// 添加OU 和域组
		Result result = adOUService.addOU(adOU);

		List<AdUser> allUserList = Lists.newArrayList();
		// 获取所有用户信息
		List<DingTalkUser> userList = dingTalkUserMapper.selectList(Wrappers.emptyWrapper());
		Map<Long, List<DingTalkUser>> userMap = userList.stream().collect(Collectors.groupingBy(DingTalkUser::getDeptIdList));
		List<AdGroup> adGroupList = listDeptInfo(deptSyncOUList, deptMap, userMap, allUserList);
		logger.info("开始向OU添加用户-------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
		// 添加用户
		if (CollectionUtil.isNotEmpty(allUserList)) {
			adUserService.addAdUser(allUserList);
		}

		try {
			// 等待三分钟
			Thread.sleep(180000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		logger.info("开始向域组添加信息-------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
		// 域组添加信息
		if (CollectionUtil.isNotEmpty(allUserList)) {
			adGroupService.addUserToGroup(adGroupList);
		}

		return result;
	}


	/**
	 * 每个部门信息封装 树形结构
	 *
	 * @param deptMap    原结果集
	 * @param deptSyncOU 需要转换的部门信息
	 * @return
	 */
	public AdOU getDeptTree(Map<Long, List<DeptSyncOU>> deptMap, DeptSyncOU deptSyncOU) {
		List<AdOU> ouList = Lists.newArrayList();
		// 部门
		List<DeptSyncOU> child = deptMap.get(deptSyncOU.getDeptId());
		if (null != child) {
			for (DeptSyncOU son : child) {
				if (!StringUtil.isEmpty(deptSyncOU.getName())) {
					son.setBasePath(getBasePath(deptSyncOU));
				}
				ouList.add(getDeptTree(deptMap, son));
			}
		}
		AdOU adOU = new AdOU();
		adOU.setName(deptSyncOU.getName());
		adOU.setBasePath(deptSyncOU.getBasePath());
		adOU.setDescription(deptSyncOU.getName());
		adOU.setChildren(ouList);
		adOU.setDeptId(deptSyncOU.getDeptId());
		return adOU;
	}

	/**
	 * 每个部门信息封装 List
	 *
	 * @return
	 */
	public List<AdGroup> listDeptInfo(List<DeptSyncOU> deptSyncOUList, Map<Long, List<DeptSyncOU>> deptMap, Map<Long, List<DingTalkUser>> userMap, List<AdUser> allUserList) {
		List<AdGroup> adGroups = Lists.newArrayList();
		List<DingTalkUser> userList;
		List<AdUser> adUserList;
		// 部门
		for (DeptSyncOU deptSyncOU : deptSyncOUList) {
			List<DeptSyncOU> child = deptMap.get(deptSyncOU.getDeptId());
			LinkedList<String> sonBasePath = Lists.newLinkedList();
			if (null != deptSyncOU.getBasePath()) {
				sonBasePath.addAll(deptSyncOU.getBasePath());
			}
			sonBasePath.add(deptSyncOU.getName());
			// 用户
			userList = userMap.get(deptSyncOU.getDeptId());
			adUserList = Lists.newLinkedList();
			if (CollectionUtil.isNotEmpty(userList)) {
				adUserList = Lists.newLinkedList();
				AdUser adUser;
				for (DingTalkUser user : userList) {
					adUser = new AdUser(user);
					adUser.setBasePath(getBasePath(deptSyncOU));
					adUserList.add(adUser);
				}
			}
			AdGroup adOU = new AdGroup();
			adOU.setName(deptSyncOU.getName());
			adOU.setDescription(deptSyncOU.getName());
			adOU.setDeptId(deptSyncOU.getDeptId());
			adOU.setBasePath(sonBasePath);
			adOU.setChildren(child);
			adOU.setUserList(adUserList);
			adGroups.add(adOU);
			allUserList.addAll(adUserList);
		}
		return adGroups;
	}


	/**
	 * ou 路径获取
	 *
	 * @param deptSyncOU
	 * @return
	 */
	private LinkedList<String> getBasePath(DeptSyncOU deptSyncOU) {
		LinkedList<String> basePath = Lists.newLinkedList();
		if (null != deptSyncOU.getBasePath()) {
			basePath.addAll(deptSyncOU.getBasePath());
		}
		basePath.add(deptSyncOU.getName());
		return basePath;
	}

}
